<template>
  <FormItemGroup
    v-if="shouldShowAdvice || formEntity.status === 2 || dev"
    class="process-advice"
    :block-title="nodeName"
    :active="active"
    :disabled="!enabled"
    :enabled="enabled">
    <template #default="{ disabled: forbidden }">
      <FormItem v-if="showAdvice" label="审批意见" block form-item-class="is-required">
        <ElForm
          ref="form"
          class="process-advice-form"
          :hide-required-asterisk="false"
          :model="entity"
          :disabled="forbidden">
          <ElFormItem prop="advice" :rules="[{ required: true, message: '请输入您的审批意见' }]">
            <ElInput
              v-model="entity.advice"
              placeholder="请输入您的审批意见"
              type="textarea"
              rows="5"
              resize="none"
              @input="emitInput" />
          </ElFormItem>
        </ElForm>
        <slot name="append" :disabled="forbidden" :agree="entity.agree"></slot>
      </FormItem>
      <slot :disabled="forbidden" :agree="entity.agree"></slot>
    </template>
  </FormItemGroup>
</template>

<script>
  import { mapState } from 'vuex'
  import { size } from 'lodash-es'

  function shouldShowAdvice(nodeCode, flowContext) {
    const ctx = flowContext || this.flowContext
    if (!ctx?.logGroup) {
      return false
    }
    const opinions = ctx?.context?.formSetting?.opinions
    if (opinions && size(opinions) > 0) {
      return ctx?.context?.formSetting?.opinions.includes(nodeCode)
    }
    let agree = false
    const logs = ctx.logGroup[nodeCode]
    if (logs?.length) {
      agree = logs[0].agree
    }
    return agree || ctx.context.nodeCode === nodeCode
  }

  export default {
    name: 'ProcessAdvice',
    inject: {
      flowContext: {
        default: {}
      },
      adviceEntity: {
        default: {}
      },
      formEntity: {
        default: {}
      }
    },
    props: {
      nodeName: String,
      nodeCode: String,
      active: Boolean,
      dev: Boolean,
      // 是否显示审批意见
      showAdvice: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        entity: {
          agree: true,
          advice: '',
          createdAt: '',
          userName: ''
        }
      }
    },
    computed: {
      ...mapState('user', ['userName']),
      enabled() {
        if (this.dev) {
          return true
        }
        return this.flowContext.context.nodeCode === this.nodeCode
      },
      shouldShowAdvice() {
        return shouldShowAdvice(this.nodeCode, this.flowContext)
      }
    },
    watch: {
      'flowContext.logGroup': {
        immediate: true,
        handler(newVal) {
          if (newVal?.[this.nodeCode]?.length) {
            const log = newVal[this.nodeCode][0]
            if (log.agree) {
              this.entity.agree = log.agree
              this.entity.advice = log.advice
              this.entity.createdAt = log.createdAt
              this.entity.userName = log.userName
              this.emitInput()
            } else {
              this.entity.agree = true
              this.entity.advice = ''
            }
          }
        }
      }
    },
    mounted() {
      this.dispatch('FlowForm.addFlowAdvice', [this])
    },
    beforeDestroy() {
      this.dispatch('FlowForm.removeFlowAdvice', [this])
    },
    methods: {
      dispatch(eventName, params) {
        let parent = this.$parent || this.$root
        let flowForm = parent.$options.flowForm

        while (parent && !flowForm) {
          parent = parent.$parent
          if (parent) {
            flowForm = parent.$options.flowForm
          }
        }
        if (parent) {
          parent.$emit.apply(parent, [eventName].concat(params))
        }
      },
      clearValidate() {
        this.$refs.form?.clearValidate()
      },
      async validate() {
        try {
          return await this.$refs.form?.validate()
        } catch (e) {
          throw Error('表单验证不通过!')
        }
      },
      emitInput() {
        if (this.dev) {
          return
        }
        if (this.flowContext.context.nodeCode === this.nodeCode) {
          this.adviceEntity.advice = this.entity.advice
          this.adviceEntity.agree = this.entity.agree
        }
      },
      getEntity() {
        return this.entity
      }
    }
  }
</script>

<style lang="scss">
  .process-advice {
    .process-advice-form {
      .el-col {
        > .el-form-item {
          > .el-form-item__content {
            position: static;
          }
        }
      }
    }
  }
</style>
